package testapp.client;


import java.util.logging.Logger;

import testapp.client.animation.AnimationCallbackPart;
import testapp.client.animation.CompositeAnimationFrame;
import testapp.client.handler.FinishEditHandler;
import testapp.client.handler.StartEditHandler;
import testapp.client.handler.SwipeNoteHandler;
import testapp.client.util.AppContext;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchEndHandler;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchMoveHandler;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.dom.client.TouchStartHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;

public class SlidableContainer extends Composite {
    private Logger logger = Logger.getLogger("main");

    interface MyUiBinder extends UiBinder<Widget, SlidableContainer> {}

    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

    @UiField FlowPanel slidableDiv;

    @UiField NotesPanel taskPanel;

    @UiField NotesPanel completedPanel;

    private int swipeStartX;

    private int scrollX;

    private boolean isNoteEdit;

    SwipeNoteHandler swipeCompletedNoteHandler = new SwipeNoteHandler() {
        @Override
        public void onSwipe(Note note) {
            completedPanel.getDelegate().remove(note);

            createTaskNoteIfNeeded(note.getLabel().getText());
        }
    };

    SwipeNoteHandler swipeTaskNoteHandler = new SwipeNoteHandler() {
        @Override
        public void onSwipe(Note note) {
            taskPanel.getDelegate().remove(note);

            createTaskNoteIfNeeded("");

            Note completedNote = completedPanel.addNote(note.getLabel().getText());

            completedNote.addStartEditHandler(new StartEditHandler() {
                @Override
                public void onStartEdit(Note note) {
                    isNoteEdit = true;
                }
            });

            completedNote.addFinishEditHandler(new FinishEditHandler() {
                @Override
                public void onFinishEdit(Note note) {
                    isNoteEdit = false;
                }
            });

            completedNote.addSwipeNoteHandler(swipeCompletedNoteHandler);
        }
    };

    public SlidableContainer() {
        initWidget(uiBinder.createAndBindUi(this));

        for (int i = 0; i < 25; i++) {
            createTaskNoteIfNeeded("First note1");
        }

        CompositeAnimationFrame.getInstance().addAnimationCallbackPart(new AnimationCallbackPart() {
            @Override
            public void execute() {
                slidableDiv.getElement().getStyle().setProperty("webkitTransform", "translateX(" + scrollX + "px)");
            }
        });

        slidableDiv.addDomHandler(new TouchStartHandler() {
            @Override
            public void onTouchStart(TouchStartEvent event) {
                if (!isNoteEdit) {
                    swipeStartX = event.getTouches().get(0).getPageX();

                    slidableDiv.getElement().getStyle().setProperty("webkitTransition", "-webkit-transform 0s linear");
                }
            }
        }, TouchStartEvent.getType());

        slidableDiv.addDomHandler(new TouchMoveHandler() {
            @Override
            public void onTouchMove(TouchMoveEvent event) {
                if (!isNoteEdit) {
                    int deltaX = event.getTouches().get(0).getPageX() - swipeStartX;

                    int unsensitiveThreshold = 15 * Window.getClientWidth() / 100;

                    if (AppContext.getInstance().getActivePanel() == 0) {
                        deltaX += unsensitiveThreshold;
                    } else {
                        deltaX -= unsensitiveThreshold;
                    }

                    if ((AppContext.getInstance().getActivePanel() == 0 && deltaX > 0)
                     || (AppContext.getInstance().getActivePanel() == 1 && deltaX < 0)) deltaX = 0;

                    scrollX = deltaX - AppContext.getInstance().getActivePanel() * Window.getClientWidth();

                    event.preventDefault();
                }
            }
        }, TouchMoveEvent.getType());

        slidableDiv.addDomHandler(new TouchEndHandler() {
            @Override
            public void onTouchEnd(TouchEndEvent event) {
                if (!isNoteEdit) {
                    int slidableDivOffset = slidableDiv.getAbsoluteLeft() * 100 / Window.getClientWidth();

                    int targetPosition;

                    if (AppContext.getInstance().getActivePanel() == 0) {
                        if (slidableDivOffset <= -10) {
                            targetPosition = -Window.getClientWidth();

                            AppContext.getInstance().setActivePanel(1);
                        } else {
                            targetPosition = 0;
                        }
                    } else {
                        if (slidableDivOffset >= -90) {
                            targetPosition = 0;

                            AppContext.getInstance().setActivePanel(0);
                        } else {
                            targetPosition = -Window.getClientWidth();
                        }
                    }

                    slidableDiv.getElement().getStyle().setProperty("webkitTransition", "-webkit-transform 0.2s ease-out");

                    scrollX = targetPosition;
                }
            }
        }, TouchEndEvent.getType());

        /*
        Window.addResizeHandler(new ResizeHandler() {
            @Override
            public void onResize(ResizeEvent event) {
                if (AppContext.getInstance().getActivePanel() == 0) {
                    scrollX = 0;
                } else {
                    scrollX = -Window.getClientWidth();
                }
            }
        });*/
    }

    private void createTaskNoteIfNeeded(String text) {
        boolean needCreating = false;

        if (taskPanel.getDelegate().getWidgetCount() == 0) {
            needCreating = true;
        } else {
            Note lastNote = (Note) taskPanel.getDelegate().getWidget(taskPanel.getDelegate().getWidgetCount() - 1);

            if (!lastNote.getLabel().getText().trim().isEmpty()) {
                needCreating = true;
            }
        }

        if (needCreating) {
            Note newNote = taskPanel.addNote(text);

            newNote.addSwipeNoteHandler(swipeTaskNoteHandler);

            newNote.addStartEditHandler(new StartEditHandler() {
                @Override
                public void onStartEdit(Note note) {
                    isNoteEdit = true;
                }
            });

            newNote.addFinishEditHandler(new FinishEditHandler() {
                @Override
                public void onFinishEdit(Note note) {
                    isNoteEdit = false;

                    createTaskNoteIfNeeded("");
                }
            });
        }
    }
}
